﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

using SmlEngine.Sprites.Base;

namespace SmlEngine.Sprites.Settings
{
    public static class TileSettings
    {
        private static Dictionary<int, Tile> tiles;

        private static Tile current;
        private static int width, height, rise, run;

        private static bool isLoaded;

        public static void Load(ContentManager content, Stream data)
        {
            if (!isLoaded)
            {
                tiles = new Dictionary<int, Tile>();

                int index = 0;
                int settingIndex = 0;
                StringBuilder builder = new StringBuilder();

                for (int i = 0; i < data.Length; i++)
                {
                    int value = data.ReadByte();

                    char character = (char)value;

                    //Read data
                    if (character == ':') //Reached next item
                    {
                        tiles.Add(index, current);
                        builder.Clear();
                        index++;
                        settingIndex = 0;
                    }
                    else if (character == ',')
                    {
                        ParseTile(settingIndex, builder.ToString(), content);
                        builder.Clear();
                        settingIndex++;
                    }
                    else if (character != '\n' && character != '\r')
                    {
                        builder.Append(character);
                    }
                }

                isLoaded = true;
            }
        }

        private static void ParseTile(int index, string value, ContentManager content)
        {
            switch(index)
            {
                case 0:
                    current = new Tile();
                    current.SetGraphics(content.Load<Texture2D>(value));
                    return;

                case 1:
                    width = Convert.ToInt32(value);
                    return;

                case 2:
                    height = Convert.ToInt32(value);
                    return;

                case 3:
                    rise = Convert.ToInt32(value);
                    return;

                case 4:
                    run = Convert.ToInt32(value);
                    return;

                case 5:
                    bool inverted = Convert.ToBoolean(Convert.ToInt32(value));

                    Vector2 angle = new Vector2(rise >= 0 ? width : 0, inverted ? 0 : height);
                    Vector2 across = new Vector2(rise >= 0 ? 0 : width, inverted ? 0 : height);
                    Vector2 up = new Vector2(rise >= 0 ? width : 0, inverted ? 0 : width);
                    Vector2 origin = new Vector2(width / 2, height / 2);

                    current.Collision = new RightTriangle(angle, across, up);
                    current.Collision.Origin = origin;

                    if (current.Collision.Gradient.Slope == 0)
                        current.Collision.IsSloped = false;
                    return;

                case 6:
                    current.Slope = (Collision)Convert.ToInt32(value);
                    return;

                case 7:
                    current.Left = (Collision)Convert.ToInt32(value);
                    return;

                case 8:
                    current.Top = (Collision)Convert.ToInt32(value);
                    return;

                case 9:
                    current.Right = (Collision)Convert.ToInt32(value);
                    return;

                case 10:
                    current.Bottom = (Collision)Convert.ToInt32(value);
                    return;
            }
        }

        public static Tile GetBehaviour(int index)
        {
            if (index < tiles.Count)
                return tiles[index];
            else
                return new Tile();
        }
    }
}
